I'm Terrence

Swift 学习笔记

.self 跟 .Type 傻傻分不清

Int.Type 是 Int 的元类型(),而 Int.Type 跟 Int.self 的关系,就是 Int 跟 5 的关系,一个是类型,一个是值

什么是元类型?

我们通过元类型,去调用这个类的 static 方法,个人感觉,有点像 oc 被类对象的 isa 指针所指向的 meta Class

1
2
3
4
5
6
7
Int.max

//实际上等价于:

Int.self.max

//只是编译器帮我们省去了这个self

protocol.Type?

首先 protocol 不是一个类型,只有他被一个类实现了,才具有元类型这个说法

show me the code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65


protocol MYStrategy {
func cal() -> Int
}


class PlanA : MYStrategy {
required init() {

}
func cal() -> Int {
return 1
}
}


class PlanB : MYStrategy {
required init() {

}
func cal() -> Int {
return 2
}
}

struct PlanFactory {

/*
根据类型推断,免去传参的烦恼
*/
static func createPlan<T: MYStrategy>() -> T? {
if let planA = T.self as? PlanA.Type {
return planA.init() as? T
}
if let planB = T.self as? PlanB.Type {
return planB.init() as? T
}
return nil
}

/*
type 传入的是一个元类型的值,由于 MYStrategy 是 protocol,这里传一个实现了 MYStrategy 的类的元类型的值即可
*/
static func createPlanV2(type: MYStrategy.Type) -> MYStrategy? {
if type == PlanA.self {
return PlanA()
}

if type == PlanB.self {
return PlanB()
}
return nil
}
}



class MainTest {
func test() {
var plan:PlanA? = PlanFactory.createPlan()

var planT = PlanFactory.createPlanV2(type: PlanA.self)
}
}

type(of:) 跟 .self

相同点:都是获取 metaType (元类型)

不同点:type(of: value), 其中参数value 是个对象实例,主要用于动态获取 value 的 元类型;而 XXX.self 是静态获取 XXX 的元类型,其中 XXX 是个类

1
2
3
4
var testString = "123"
var a = type(of: testString) //String
var b = String.self //String
var c = testString.self // 123

Self

在协议中用得比较多用来表示遵循这个协议的对象
这里用例子自定义命名空间的例子来说明一下(仿照rxSwift)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
这个 struct 作为命名空间 Xr
Base 是泛型
*/
public struct Xr<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
}

/*
协议 + 关联类型
一个静态 getter, 一个实例 getter
*/
public protocol XrCompatible {
associatedtype XrBase
static var xr: Xr<XrBase>.Type { get }
var xr: Xr<XrBase> { get }
}

/*
扩展 XrCompatible,写默认实现
限定 Base 类型为 Self
*/
extension XrCompatible {

//这里的几个 Self, 是给 Xr 的<Base> 泛型做了限制,限制为遵循这个协议的对象本身

//静态 xr getter,用于扩展类方法
public static var xr: Xr<Self>.Type {
get { Xr<Self>.self }
}

//实例 xr getter,用于扩展实例方法
public var xr: Xr<Self> {
get { Xr(self) }
}
}


/*
赋予以下类 XrCompatible 的能力,可以直接用默认实现的两个 getter 来玩,让他们有了 XX.xr 的命名空间
*/
extension NSObject: XrCompatible { }
extension String: XrCompatible { }
extension Data: XrCompatible { }


/*
对 Xr 且 base 是 String 类型的进行扩展,新增方法 appendHaha
*/
extension Xr where Base == String {
func appendHaha() -> String {
return base+"haha"
}
}


let testString = "123".xr.appendHaha()
// 123haha